package com.sy.controller.admin;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sy.constant.JwtClaimsConstant;
import com.sy.context.BaseContext;
import com.sy.dto.EmployeeDTO;
import com.sy.dto.EmployeeLoginDTO;
import com.sy.dto.EmployeePageQueryDTO;
import com.sy.pojo.Employee;
import com.sy.properties.JwtProperties;
import com.sy.result.PageResult;
import com.sy.result.Result;
import com.sy.service.EmployeeService;
import com.sy.utils.JwtUtil;
import com.sy.vo.EmployeeLoginVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 员工管理
 */
@Api(tags = "员工相关接口")
@RestController
@RequestMapping("/admin/employee")
@Slf4j
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private JwtProperties jwtProperties;



    /**
     * 登录
     * @param employeeLoginDTO 客户端向服务器端发送请求携带的参数 封装到dto中
     * @return
     * @RequestBody : 对客户端发送的json格式数据转成对象
     * @ResponseBody : 对服务端的对象转成json格式数据
     */
    @ApiOperation("登录")
    @PostMapping("/login")
    public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {
        log.info("员工登录：{}", employeeLoginDTO);
        Employee employee = employeeService.login(employeeLoginDTO);

        // 登录成功后的用户信息保存token中
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.EMP_ID, employee.getId());
        // 秘钥
        String token = JwtUtil.createJWT(jwtProperties.getAdminSecretKey(),
                jwtProperties.getAdminTtl(),
                claims);

        //把当前登录用户信息响应给前台，展示当前登录用户名
        EmployeeLoginVO employeeLoginVO=new EmployeeLoginVO();
        //把employee中的信息赋值到employeeLoginVO，返回的都是一些不敏感的信息
        BeanUtils.copyProperties(employee,employeeLoginVO);
        employeeLoginVO.setToken(token);

        return Result.success(employeeLoginVO);
    }

    /**
     * 退出
     *
     * @return
     */
    @ApiOperation("登出")
    @PostMapping("/logout")
    public Result<String> logout() {
        //打印请求数据日志
        log.info("员工退出系统成功...");
        return Result.success();
    }

    /**
     * 员工分页查询
     * @param employeePageQueryDTO
     * @return
     */
    @ApiOperation("员工分页查询")
    @GetMapping("/findAll")
    public Result<PageResult> findAll(EmployeePageQueryDTO employeePageQueryDTO) {
        //打印请求数据日志
        log.info("员工分页查询：{}", employeePageQueryDTO);
        // 调用业务层实现分页查询
        PageResult pageResult = employeeService.findAll(employeePageQueryDTO);
        return Result.success(pageResult);
    }

    /**
     * 查询用户名是否存在
     * @param username
     * @return
     */
    @ApiOperation("查询用户名是否存在")
    @GetMapping("/doExistUsername")
    @ApiImplicitParams(
            @ApiImplicitParam(value = "要验证的用户名", name = "username",
                    required = true, dataTypeClass = String.class)
    )
    public Result<String> doExistUsername(String username) {
        //打印请求数据日志  select * from employee where username = '';
        log.info("用户名为：{}", username);
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Employee::getUsername, username);
        Employee employee = employeeService.getOne(queryWrapper);
        if (employee == null){
            return Result.success();
        } else {
            return Result.error("用户名已存在");
        }
    }

    /**
     * 查询手机号是否存在
     * @param phone
     * @return
     */
    @ApiOperation("查询手机号是否存在")
    @GetMapping("/doExistPhone")
    @ApiImplicitParams(
            @ApiImplicitParam(value = "要验证的用户名", name = "phone",
                    required = true, dataTypeClass = String.class)
    )
    public Result<String> doExistPhone(String phone) {
        //打印请求数据日志  select * from employee where phone = '';
        log.info("用户名为：{}", phone);
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Employee::getPhone, phone);
        Employee employee = employeeService.getOne(queryWrapper);
        if (employee == null){
            return Result.success();
        } else {
            return Result.error("手机号已存在");
        }
    }

    /**
     * 新增员工信息
     * @param employeeDTO
     * @return
     */
    @ApiOperation("新增员工信息")
    @PostMapping("/save")
    public Result save(@RequestBody EmployeeDTO employeeDTO) {
        try {
            //打印请求数据日志
            log.info("新增员工信息：{}", employeeDTO);
            // 新增员工信息
            employeeService.saveEmp(employeeDTO);
        } catch (Exception e) {
            throw new RuntimeException("新增员工失败");
        }
        return Result.success();
    }

    /**
     * 修改员工信息
     * @param employeeDTO
     * @return
     */
    @ApiOperation("修改员工信息")
    @PostMapping("/update")
    public Result update(@RequestBody EmployeeDTO employeeDTO) {
        try {
            //打印请求数据日志
            log.info("修改员工信息：{}", employeeDTO);
            // 处理下  客户端传递的数据封装到EmployeeDTO 复制 给Employee对象
            Employee employee = new Employee();
            BeanUtils.copyProperties(employeeDTO, employee);
            // Employee就已经存在了 真实姓名 手机号  性别  员工状态
            // 设置修改时间
            employee.setUpdateTime(LocalDateTime.now());
            // 设置修改人
            employee.setUpdateUser(BaseContext.getCurrentId());
            // 修改员工信息
            employeeService.updateById(employee);
        } catch (Exception e) {
            throw new RuntimeException("修改员工失败");
        }
        return Result.success();
    }

    /**
     * 员工删除
     * @param ids
     * @return
     */
    @ApiOperation("员工删除")
    @PostMapping("/delete")
    @ApiImplicitParams(
            @ApiImplicitParam(value = "是一个List集合, 存储要删除的员工id", name = "ids",
                    required = true, dataTypeClass = List.class)
    )
    public Result delete(@RequestBody List<Long> ids) {
        //打印请求数据日志  select * from employee where phone = '';
        log.info("员工删除的数据：{}", ids);
        try {
            // 1. 获取当前员工的id
            Long empId = BaseContext.getCurrentId();
            // 2. 实现删除
            // 判断当前员工id 在 ids 中是否包含(存在)
            if (ids.contains(empId)){
                // 如果存在 不能删除
                return Result.error("不可以删除当前登录用户");
            } else{
                // 如果不存在进行逻辑删除(修改)
                // update 表名 set isDelete = 0 where id in [2, 3]
                LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.in(Employee::getId, ids);
                // 修改指定字段
                Employee employee = new Employee();
                employee.setIsDelete(0);
                employee.setUpdateTime(LocalDateTime.now());
                // employee.setUpdateUser(BaseContext.getCurrentId());
                // 实现逻辑删除操作
                employeeService.update(employee, queryWrapper);
                return Result.success();
            }
        } catch (Exception e) {
            throw new RuntimeException("删除失败");
        }

    }

    /**
     * 校验原密码是否正确
     * @param password
     * @return
     */
    @ApiOperation("校验原密码是否正确")
    @GetMapping("/getEmpByPassword")
    @ApiImplicitParams(
            @ApiImplicitParam(value = "当前登录员工的密码", name = "password",
                    required = true, dataTypeClass = String.class)
    )
    public Result getEmpByPassword(String password) {
        // 获取当前用户输入的登录密码  通过md5进行加密
        String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
        // 获取当前登录用户保存在数据库的密码
        Long empId = BaseContext.getCurrentId();
        // 根据员工id查询数据库
        Employee employee = employeeService.getById(empId);
        // 判断输入的密码  和  从数据库查询的密码  是否一致
        if (employee.getPassword().equals(md5Password)){
            return Result.success();
        } else {
            return Result.error("密码输入错误, 请重新输入...");
        }
    }

    /**
     * 修改密码
     * @param password
     * @return
     */
    @ApiOperation("修改密码")
    @PostMapping("/updatePassword")
    @ApiImplicitParams(
            @ApiImplicitParam(value = "员工的新密码", name = "password",
                    required = true, dataTypeClass = String.class)
    )
    public Result updatePassword(String password) {
        try {
            // 获取当前用户输入的登录密码  通过md5进行加密
            String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
            // 获取当前登录的用户
            Long empId = BaseContext.getCurrentId();
            // 创建员工对象
            Employee employee = new Employee();
            employee.setId(empId);
            employee.setPassword(md5Password);
            // 修改操作
            employeeService.updateById(employee);
            return Result.success();
        } catch (Exception e) {
            throw new RuntimeException("密码修改失败...");
        }

    }




    /*@RequestMapping("/newTime")
    public LocalDateTime newTime() {
        return LocalDateTime.now();
    }*/

}
